root = "./"
luaservice 	= root .. "service/?.lua;" .. root .. "test/?.lua;" .. root .. "examples/?.lua;"
lua_path 	= root .. "lualib/?.lua;"  .. root .. "skynet/lualib/?.lua;"
lua_cpath 	= root .. "luaclib/?.so;"  .. root .. "skynet/luaclib/?.so;"
snax 		= root .. "client/?.lua;"


package.path = luaservice .. lua_path .. snax .. package.path 
package.cpath = lua_cpath .. package.cpath

-----------------------------------------------------------------

if _VERSION ~= "Lua 5.4" then
	error "Use lua 5.4"
end

local socket = require "client.socket"
local crypt = require "client.crypt"
local socklib = require "socklib"

local sproto = require "sproto"
local sprotoparser = require "sprotoparser"

local f = assert(io.open("proto/s2c.sproto", "r"))
local s2c = f:read("*a")
f:close()

local f = assert(io.open("proto/c2s.sproto", "r"))
local c2s = f:read("*a")
f:close()

local host = sproto.new(sprotoparser.parse(s2c)):host "package"
local request = host:attach(sproto.new(sprotoparser.parse(c2s)))

local login_host, login_port
local gate_host, gate_port 
local servername, username, password 
local signup_port = 8081 -- 默认，就不传了

-- 获取参数
if #arg == 6 then
	login_host = arg[1]
	login_port = tonumber(arg[2])
	gate_host = arg[3]
	gate_port = tonumber(arg[4])

	username = arg[5]
	password = arg[6]
else
	print("【 Usage : lua client.lua login_host login_port gate_host gate_port username password 】")
	os.exit()
end

local REQ_FROM_SERVER = {}
local RESP_FROM_SERVER = {}

local session = 0 
local session_map = {}
local handshake_index = 1

local function send_request(name, args)
	session = session + 1
	session_map[session] = name

	local str = request(name, args, session)
	socklib.send_package(str)
end

local function handle_package(t, ...)
	local arr = {...}
	if t == "REQUEST" then
		local name = arr[1]
		local args = arr[2]
		print(t, name, args)

		assert(REQ_FROM_SERVER[name], "no REQ_FROM_SERVER handler found for: " .. name)
		local f = REQ_FROM_SERVER[name]
		f(args)
	elseif t == "RESPONSE" then
		local session = arr[1]
		local args = arr[2]
		print(t, session, args)

		local name = session_map[session]
		if name then
			session_map[session] = nil

			assert(RESP_FROM_SERVER[name], "no RESP_FROM_SERVER handler found for: " .. name)
			local f = RESP_FROM_SERVER[name]
			f(args)
		end
	end
end

local function dispatch_package()
	while true do
		local v = socklib.try_read_package()
		if not v then
			break
		end
		handle_package(host:dispatch(v))
	end
end



-------------------- REQ_FROM_SERVER -----------------------

function REQ_FROM_SERVER.enter_room_message(args)
	print("【enter_room_message】 " .. " uid : " .. args.uid, " roomid : " .. args.roomid, " username : " .. args.username)
end 

function REQ_FROM_SERVER.leave_room_message(args)
	print("【leave_room_message】 " .. " uid : " .. args.uid, " roomid : " .. args.roomid, " username : " .. args.username)
end 

function REQ_FROM_SERVER.say_public_message(args)
	print(args.msg)
end 

function REQ_FROM_SERVER.say_private_message(args)
	print(args.from, args.msg)
end 

function REQ_FROM_SERVER.kick_message(args)
	print(args.msg)
end 

function REQ_FROM_SERVER.send_exp_message(args)
	print(args.msg)
end 

-------------------- RESP_FROM_SERVER -----------------------

function RESP_FROM_SERVER.afk(args)
	print(args)
end 

function RESP_FROM_SERVER.logout(args)
	print(args)
end 

function RESP_FROM_SERVER.enter_room(args)
	print(args.ok)
end 

function RESP_FROM_SERVER.leave_room(args)
	print(args.ok)
end 

function RESP_FROM_SERVER.list_members(args)
	require "utils".print_table(args.members)
end 

function RESP_FROM_SERVER.list_rooms(args)
	require "utils".print_table(args.rooms)
end 

function RESP_FROM_SERVER.say_public(args)
end 

function RESP_FROM_SERVER.say_private(args)
end 

function RESP_FROM_SERVER.kick(args)
	print(args.ok)
end 

function RESP_FROM_SERVER.send_exp(args)
	print(args.ok)
end 

---------------------------- loop ----------------------------

function loop(login_host, login_port, gate_host, gate_port, username, password)
	socklib.set_signup_conf(login_host, signup_port)
	socklib.set_login_conf(login_host, login_port)
	socklib.set_gate_conf(gate_host, gate_port)
	socklib.set_credential("server1", username, password)

	-- signup Logic 
	print("trying to sign up with login server")
	local ok, resp = pcall(socklib.connect_login_server_signup)
	if not ok or not resp.ok then 
		os.exit()
	end

	-- communicate with login server
	print("trying to login with login server")
	local ok, result = pcall(socklib.connect_login_server)
	if not ok or not result or not result.ok then
		print("connect to login server failed")
		os.exit()
	else
		uid = result.uid 
		subid = result.subid
		servername = result.servername
		gameserver = result.gameserver
		secret = result.secret
	end

	local ok, result = pcall(socklib.connect_gate_server, servername, uid, handshake_index, secret)
	if not ok or not result then 
		print("auth with gate server failed")
		os.exit()
	end 

	print("~~~ game server login succ ~~~")
	while true do 
		dispatch_package()
		local stdin = socket.readstdin()
		if stdin then 
			local args = {} 
			for w in string.gmatch(stdin, "%S+") do 
				args[#args + 1] = w 
			end 

			local cmd = args[1]

			if cmd == "afk" then 
				send_request(cmd, {})
			elseif cmd == "logout" then
				send_request(cmd, {})
				break 
			elseif cmd == "enter_room" then 
				send_request("enter_room", { id = args[2] or 1 })
			elseif cmd == "leave_room" then 
				send_request("leave_room", {})
			elseif cmd == "list_members" then 
				send_request("list_members", {})
			elseif cmd == "list_rooms" then 
				send_request("list_rooms", {}) 
			elseif cmd == "say_public" then 
				send_request("say_public", { msg = args[2] }) 
			elseif cmd == "say_private" then 
				if uid == 524328479 then 
					send_request("say_private", { to = 748234254, msg = "I'm 524328479" }) 
				else 
					send_request("say_private", { to = 524328479, msg = "I'm 748234254" }) 
				end 
			elseif cmd == "kick" then 
				if uid == 524328479 then 
					send_request("kick", { from = 524328479, to = 748234254 }) 
				else 
					send_request("kick", { from = 748234254, to = 524328479 }) 
				end 
			elseif cmd == "send_exp" then 
				if uid == 524328479 then 
					send_request("send_exp", { from = 524328479, to = 748234254, exp = args[2] })
				else
					send_request("send_exp", { from = 748234254, to = 524328479, exp = args[2] }) 
				end  
			end 
		end 
	end 

end 

loop(login_host, login_port, gate_host, gate_port, username, password)